package com.itjiange.reglg.controller;

import cn.hutool.core.lang.UUID;
import cn.hutool.core.lang.Validator;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.itjiange.reglg.common.BaseResponse;
import com.itjiange.reglg.common.ErrorCode;
import com.itjiange.reglg.constant.CommonConstant;
import com.itjiange.reglg.constant.UserConstant;
import com.itjiange.reglg.exception.BussinessException;
import com.itjiange.reglg.model.vo.CaptchaVO;
import com.itjiange.reglg.model.vo.PublicKeyVO;
import com.itjiange.reglg.service.EmailService;
import com.itjiange.reglg.utils.*;
import com.wf.captcha.SpecCaptcha;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.Map;

/**
 * 通用控制类
 *
 * @author ItJiange
 * @date 2023/11/14
 */
@RestController
@CrossOrigin("*")
public class CommonController {

    @Resource
    private RedisUtils redisUtils;

    @Resource
    private EmailService emailService;

    /**
     * 获取公钥
     *
     * @return
     */
    @GetMapping("/publicKey")
    public BaseResponse<PublicKeyVO> common() {
        // 获取公私钥
        Map<Integer, String> map = RSAUtils.genKeyPair();
        String publicKey = map.get(1);
        String privateKey = map.get(0);
        // 将私钥存入 Redis
        String uuid = UUID.randomUUID().toString();
        String keyUUID = CommonConstant.PRIVATE_KEY.concat(uuid);
        redisUtils.setKV(keyUUID, privateKey, 600);
        // 将key和base64返回给前端
        PublicKeyVO publicKeyVo = new PublicKeyVO();
        publicKeyVo.setPublicKeyUUID(keyUUID); // 响应 uuid
        publicKeyVo.setPublicKey(publicKey); // 将公钥存入 res 中
        return ResultUtils.success(publicKeyVo);
    }

    /**
     * 获取验证码
     * @return
     */
    @GetMapping("/captcha")
    public BaseResponse<CaptchaVO> getCaptcha() {
        // 获取验证码
        SpecCaptcha specCaptcha = new SpecCaptcha(130, 48, 5);
        String verCode = specCaptcha.text().toLowerCase();
        // 获取验证码 uuid、图片信息
        String uuid = UUID.randomUUID().toString();
        String images = specCaptcha.toBase64();
        // 存入验证码并设置过期时间为 60 秒钟
        String captchaUUID = CommonConstant.CAPTCHA.concat(uuid);
        redisUtils.setKV(captchaUUID, verCode, 60);
        // 将验证码信息映射到 CaptchaVO 类中
        CaptchaVO captchaVO = new CaptchaVO();
        captchaVO.setCaptchaUUID(captchaUUID);
        captchaVO.setImages(images);
        return ResultUtils.success(captchaVO);
    }

    /**
     * 判断是否已登录
     * @param token
     * @return
     */
    @GetMapping("/getToken")
    public BaseResponse<String> getUserLoginState(@RequestParam String token) {
        String tokenKey = token == null ? CommonConstant.IS_EMPTY_STATE : token;
        // 查询 Redis 中是否还存在免登录信息
        if (!redisUtils.ifHasKey(tokenKey)) {
            return ResultUtils.error(ErrorCode.NOT_FOUND_ERROR, "登录信息已过期");
        }
        return ResultUtils.success(UserConstant.USER_LOGIN_STATE);
    }

    /**
     * 发送邮件验证码
     * @param email
     * @return
     */
    @PostMapping("/sendEmail")
    public BaseResponse<String> registerByEmail(String email) {
        // 当输入的邮箱为空时
        if (StrUtil.isEmptyIfStr(email)) {
            throw new BussinessException(ErrorCode.NOT_FOUND_ERROR);
        }
        // 当输入的数据不是邮箱时
        if (!Validator.isEmail(email)) {
            throw new BussinessException(ErrorCode.PARAMS_ERROR, "邮箱格式有误");
        }
        // 生成验证码
        String verCode = RandomUtil.randomInt(1000, 9999) + "";
        // 将生成的验证码存入 Redis 中
        redisUtils.setKV(email, verCode, 300);
        // 将验证码以邮件的形式发送至目标邮箱
        emailService.sendVerCodeEmail(verCode, email);
        return ResultUtils.success("验证码已发送至邮箱");
    }
    
    /**
     * 发送手机验证码
     * @param phone
     * @return
     */
    @PostMapping("/sendPhone")
    public BaseResponse<String> registerByPhone(String phone) {
        // 当输入的电话为空时
        if (StrUtil.isEmptyIfStr(phone)) {
            throw new BussinessException(ErrorCode.NOT_FOUND_ERROR);
        }
        // 当输入的数据不是电话时
        if (!Validator.isMobile(phone)) {
            throw new BussinessException(ErrorCode.PARAMS_ERROR, "电话格式有误");
        }
        // 生成验证码
        String verCode = RandomUtil.randomInt(1000, 9999) + "";
        // 将生成的验证码存入 Redis 中
        redisUtils.setKV(phone, verCode, 300);
        // 将验证码以邮件的形式发送至目标电话
        AliyunSmsUtils.sendSms(phone, verCode);
        return ResultUtils.success("验证码已发送至电话");
    }
}
